package com.newvpn.fastbest.zenith.presenter;

import android.app.Activity;

import com.newvpn.fastbest.zenith.activity.MainActivity;
import com.newvpn.fastbest.zenith.beans.netbeans.NetServerListBean;
import com.newvpn.fastbest.zenith.beans.netbeans.VpnInfo;
import com.newvpn.fastbest.zenith.utils.VLog;
import com.newvpn.fastbest.zenith.vpn.SSManager;
import com.newvpn.fastbest.zenith.vpn.VPNCallback;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.subjects.BehaviorSubject;

public enum VPNPresenter {
    INSTANCE;


    SSManager SSManager;

    private long remainTime;
    private long runningTime;

    //private String mConnectIP;
    //private String mConnectCountry;
    private VPNReulst vpnResult = new VPNReulst();

    private VPNDetailInfo lastConnectVPNDetailInfo,currConnectVPNDetailInfo;





    public void init(MainActivity activity){
        SSManager = new SSManager(activity);
        lastConnectVPNDetailInfo = VPNDetailInfo.VPNPrefs.getVPNDetailInfo();
    }

//    public VPNDetailInfo getCurrConnectVPNDetailInfo() {
//        return currConnectVPNDetailInfo;
//    }

    private List<VpnInfo> allList;

    public List<VpnInfo> getAllList() {
        return allList;
    }

    public void setAllList(List<VpnInfo> allList) {
        this.allList = allList;
    }

    public void setCurrConnectVPNDetailInfo(VPNDetailInfo currConnectVPNDetailInfo) {
        this.currConnectVPNDetailInfo = currConnectVPNDetailInfo;
    }

    public VPNDetailInfo getLastConnectVPNDetailInfo() {
        if (lastConnectVPNDetailInfo == null){
            lastConnectVPNDetailInfo =  VPNDetailInfo.VPNPrefs.getVPNDetailInfo();
        }
        return lastConnectVPNDetailInfo;
    }



    public void setLastConnectVPNDetailInfo(VPNDetailInfo lastConnectVPNDetailInfo) {
        if (lastConnectVPNDetailInfo == null){
            return;
        }
        this.lastConnectVPNDetailInfo = lastConnectVPNDetailInfo;
        VPNDetailInfo.VPNPrefs.saveVPNDetailInfo(lastConnectVPNDetailInfo);
    }

    public boolean isConnected(){
        return vpnResult.vpnStatus == vpnResult.STATE_CONNECTED;
    }

    private long currConnectSession;

//    public void setConnectSession(String currConnectSession) {
//        this.currConnectSession = currConnectSession;
//    }

    public long preStartAction() {
        currConnectSession = System.currentTimeMillis();
        return currConnectSession;
    }

    public long getCurrConnectSession(){
        return currConnectSession;
    }


    public void connectBest(VPNDetailInfo vpnDetailInfo, long session,String ip, NetServerListBean.ServiceInfoDetail server, ConnectBestCallback callback, boolean hasConnected) {
//        JSONArray params = parseSsUrl(server.accessUrl);
//        setCurrParams(params);
        SSManager.startVPN(ip,server, new VPNCallback() {
        //outlineManager.execute(OutlineManager.Action.START.value, params, new VPNCallback() {
            @Override
            public void success() {
                if (currConnectSession != session){
                    return;
                }
                setCurrConnectVPNDetailInfo(vpnDetailInfo);
                setLastConnectVPNDetailInfo(vpnDetailInfo);
                callback.success(vpnDetailInfo);
                startAction();
//                SSManager.setVPNLiveLister(params, new VPNLiveCallback() {
//                    @Override
//                    public void result(boolean isLive) {
//                        //Log.e("isLive",isLive+"");
//                    }
//                });
            }

            @Override
            public void error(int errorCode) {
                if (currConnectSession != session){
                    return;
                }
                callback.fail(errorCode);
                endAction();
                //super.error(errorCode);
                //connectVpnError(virtualProgressManager);
                //Toast.makeText(MainActivity.this, "VPN Connection Failed：" + errorCode, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void trafficUpdated(long txRate, long rxRate) {
                callback.trafficUpdated( txRate,  rxRate);
            }

            @Override
            public void stop() {
                callback.stop();
            }

        },hasConnected);
    }



//    private void setCurrParams(JSONArray params) {
//        vpnResult.connectVpnParams = params;
//        if (vpnResult.connectVpnParams == null){
//            Log.e("NEWVPN1","connectVpnParams == null");
//        }else {
//            Log.e("NEWVPN1",params.toString());
//        }
//    }

//    private JSONArray getCurrParams(){
//        return vpnResult.connectVpnParams;
//    }

    public void disConnectAction() {
        //JSONArray params = getCurrParams();
        //outlineManager.execute(OutlineManager.Action.STOP.value, params,null);
        SSManager.stopVPN();
    }

//    public void disConnect(ConnectBestCallback callback) {
//        //JSONArray params = getCurrParams();
//        SSManager.stopVPN();
////        SSManager.stopVPN(params, new VPNCallback() {
////        //outlineManager.execute(OutlineManager.Action.STOP.value, params, new VPNCallback() {
////            @Override
////            public void success() {
////                if (callback != null){
////                    callback.success();
////                }
////                endAction();
////            }
////
////            @Override
////            public void error(int errorCode) {
////                if (callback != null){
////                    callback.fail(errorCode);
////                }
////                //super.error(errorCode);
////                //connectVpnError(virtualProgressManager);
////                //Toast.makeText(MainActivity.this, "VPN Connection Failed：" + errorCode, Toast.LENGTH_SHORT).show();
////            }
////        });
//    }


    private void startAction(){
        remainTime = 0;
        runningTime = 0;

    }

    private void endAction(){
        remainTime = 0;
        runningTime = 0;
//        mConnectIP = "";
//        mConnectCountry = "";
        setCurrServerId("");
        //setCurrParams(null);
    }


    private void setCurrServerId(String serverId) {
        vpnResult.mCurrServerId = serverId;
    }

    public String getCurrServerId() {
        return vpnResult.mCurrServerId;
    }



    private BehaviorSubject<Integer> countdownSubject;
    private Disposable countdownDisposable;
    public void startCountdown(int initialSeconds) {
        // 初始化倒计时，初始时间为initialSeconds

        countdownSubject = BehaviorSubject.createDefault(initialSeconds);
        // 启动倒计时
        startCountdown();
    }



    private void startCountdown() {
        //Log.e("NewVPN1","连接成功后，开启倒计时");
        if (countdownDisposable != null){
            countdownDisposable.dispose();
        }
        countdownSubject
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(seconds -> {
                    if (seconds <= 0){
                        for (CountdownCallback callback:countdownCallbackList){
                            callback.finish();
                        }
                        countdownDisposable.dispose();
                    }else {
                        for (CountdownCallback callback:countdownCallbackList){
                            callback.countdown(seconds);
                        }
                    }
                })
                .doOnComplete(() -> {

                })
                .subscribe();

        // 每秒减少1
        countdownDisposable =countdownSubject
                .delay(1, TimeUnit.SECONDS)
                .map(seconds -> Math.max(0, seconds - 1))
                .subscribe(countdownSubject::onNext, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        throwable.printStackTrace();
                    }
                });
    }

    public void afterDisConnect() {
        currConnectSession = 0;
        //vpnResult.currVpnInfoServer = null;
        clearCountdownCallback();
        endAction();
        setVpnStatus(vpnResult.STATE_DISCONNECT);
    }

    public void beginConnect() {
        setVpnStatus(vpnResult.STATE_CONNECTING);
    }

    public void afterConnected(String serverId) {
        setVpnStatus(vpnResult.STATE_CONNECTED);
        setCurrServerId(serverId);
    }

    private String getVpnStatusName(int status){
        if (status== VPNReulst.STATE_DISCONNECT){
            return "STATE_DISCONNECT";
        }
        if (status== VPNReulst.STATE_CONNECTING){
            return "STATE_CONNECTING";
        }
        if (status== VPNReulst.STATE_CONNECTED){
            return "STATE_CONNECTED";
        }
        if (status== VPNReulst.STATE_CONNECTED_PRE){
            return "STATE_CONNECTED_PRE";
        }
        if (status== VPNReulst.STATE_CONNECT_NEXT){
            return "STATE_CONNECT_NEXT";
        }
        if (status== VPNReulst.STATE_CONNECTED_LOADADING){
            return "STATE_CONNECTED_LOADADING";
        }
        return "";
    }

    public void setVpnStatus(int stateConnected) {
        VLog.e(getVpnStatusName(vpnResult.getVPNStatus())+"-->"+getVpnStatusName(stateConnected));
        vpnResult.setVpnStatus(stateConnected);
    }


    public void setConnectingVpnInfoServer(VPNDetailInfo server) {
        vpnResult.currVpnInfoServer = server;
    }

    public VPNDetailInfo getConnectingVpnInfoServer() {
        return  vpnResult.currVpnInfoServer;
    }

    public void setConnectedVpnInfoServer(VPNDetailInfo server) {
        vpnResult.connectedVpnInfoServer = server;
    }

    public VPNDetailInfo getConnectedVpnInfoServer() {
        return  vpnResult.connectedVpnInfoServer;
    }


    public VPNDetailInfo getSelectVPNDetail() {
        return vpnResult.selectVpnInfoServer;
    }

    public void setSelectVPNDetail(VPNDetailInfo server) {
        vpnResult.selectVpnInfoServer = server;
    }



//    public void setVPNDetailInfo(VPNDetailInfo mVPNDetailInfo) {
//        this.vpnResult.currVpnInfoServer = mVPNDetailInfo;
//    }



    public int getVPNStatus() {
        return  vpnResult.getVPNStatus();
    }




    //VpnsListActivity.VPNDetailInfo mVPNDetailInfo;





    boolean needReconnect = false;

    public boolean isNeedReconnect() {
        return needReconnect;
    }

    public void setNeedReconnect(boolean needReconnect) {
        this.needReconnect = needReconnect;
    }

    public void unbindService(Activity activity) {
        SSManager.unbindService(activity);
    }

    public interface CountdownCallback{
        void countdown(int seconds);
        void finish();
    }

    private List<CountdownCallback> countdownCallbackList = new ArrayList<>();

    public void addCountdownCallback(CountdownCallback callback){
        countdownCallbackList.add(callback);
    }

    public void clearCountdownCallback(){
        countdownCallbackList.clear();
    }


//
//    public void addTime(int additionalSeconds) {
//        // 获取当前剩余时间，并增加额外的时间
//        int currentSeconds = countdownSubject.getValue();
//        countdownSubject.onNext(currentSeconds + additionalSeconds);
//    }

    public interface ConnectBestCallback{
        void success(VPNDetailInfo vpnDetailInfo);
        void fail(int code);
        void trafficUpdated(long txRate, long rxRate);
        void stop();
    }
}
